#define _CRT_SECURE_NO_WARNINGS 1


/*
操作符详解
二进制
二进制转8进制，从二进制的右边向左边数三位读取，不足就直接转换，以0开头  --  111 - 7
二进制转16进制，从二进制的右边向左边数四位读取，不足就直接转换，以0x开头 -- 1111 -15

原码、反码、补码
1.整数的2进制表示方法有三种，即原码、反码和补码

2.有符号整数的三种表示方法均有符号位和数值位两部分，
2进制序列中，最高位的1位是被当做符号位，剩余的都是数值位
 
 如:
 int a = -7;
 1 0000000000000000000000000000111  原码
 
 第一位是符号位
 1  --  负数
 0  --  正数

 1 1111111111111111111111111111000   反码

原码的符号位不变，其他位依次按位取反，就可以得到反码

1 1111111111111111111111111111000    补码

反码+1就得到补码


3.符号位都是用0表示“正”，用1表示“负”
4.正整数的原、反、补码都相同
5.负整数的三种表示方法各不相同

6.原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码
7.反码:将原码的符号位不变，其他位依次按位取反就可以得到反码
8.补码:反码+1就得到补码
9.补码得到原码也是可以使用:取反，+1的操作


对于整形来说:数据存放内存中其实存放的是补码

在计算机系统中，数值一律用补码来表示和存储
原因在于，使用补码，可以将符号位和数值域统一处理;
同时，加法和减法也可以统一处理(CPU只有加法器)此外
补码与原码相互转换，其运算过程是相同的，不需要
额外的硬件电路

*/
//#include <stdio.h>
//
//int main()
//{
//	printf("%d\n", 15);
//	printf("%d\n", 0xf);//16进制 -- 16进制的数值之前要写0x
//	printf("%d\n", 017);//8进制  -- 8进制的数值之前要写0
//
//	return 0;
//}



#include <stdio.h>

//int main()
//{
//    int i;
//    int n = 10;
//    int arr[n];
//    for(i = 0;i < n;i++)
//    {
//        arr[i] = 0;
//        printf("%d ",arr[i]);
//    }
//
//
//    return 0;
//}

/*
操作符
 移位操作符
 <<  左移  -- 移动的是二进制序列(移动的是内存中的补码)
 >>  右移  -- 移动的是二进制序列(移动的是内存中的补码)

 左移操作符
规则 - 左边抛弃，右边补0

 右移操作符
移位规则: 首先右移运算分为两种
1.逻辑右移:左边用0填充，右边丢弃
2.算术右移:左边用原该值的符号位填充，右边丢弃

右移到底是算术右移，还是逻辑右移，取决于编译器
但是大部分编译器采用的是算术右移

*对于移位运算符，不要移动负数位，这个是标准未定义的
如:
int a = 10;
a << -1; //error

*/

//左移操作符
//int main()
//{
//    int n = 12;
//    //00000000 00000000 00000000 00001100  //12
//
//    int m = n << 1;//左移
//    //00000000 00000000 00000000 00011000  //24
//
//
//    printf("%d ",m);
//    printf("%d ",n);
//    return 0;
//}


//int main()
//{
//    int a = -10;
//    //10000000 00000000 00000000 00001010
//    //11111111 11111111 11111111 11110101
//    //11111111 11111111 11111111 11110110   a的补码
//
//    int b = a << 1;
//
//    //11111111 11111111 11111111 11101100   b的补码
//
//    //10000000 00000000 00000000 00010100   b的原码 -20
//    printf("%d\n",b);
//    printf("%d\n",a);
//
//    return 0;
//}

//右移操作符
//移位规则: 首先右移运算分为两种
//1.逻辑右移:左边用0填充，右边丢弃
//2.算术右移:左边用原该值的符号位填充，右边丢弃

//右移到底是算术右移，还是逻辑右移，取决于编译器
//但是大部分编译器采用的是算术右移

int main()
{
    int a = -10;
    //10000000 00000000 00000000 00001010
    //11111111 11111111 11111111 11110101
    //11111111 11111111 11111111 11110110   a的补码

    int b = a >> 1;

    //11111111 11111111 11111111 11111011   b的补码

    //10000000 00000000 00000000 00000101   b的原码 -5
    printf("%d\n", b);
    printf("%d\n", a);

    return 0;
}
